<template>
  <a-drawer
    :title="data?.id ? '编辑脚本' : '新增脚本'"
    :visible="visible"
    :width="980"
    :destroyOnClose="true"
    :keyboard="false"
    :maskClosable="false"
    @close="handleCancel"
    :body-style="{ paddingBottom: '60px' }"
  >
    <a-form :model="scriptData">
      <a-page-header title="基本信息" />
      <a-form-item v-bind="validateInfos.title" label="脚本名称">
        <a-input
          style="width: 400px"
          placeholder="请输入脚本名称"
          v-model:value="scriptData.title"
        />
      </a-form-item>
      <!-- <a-form-item v-bind="validateInfos.script_line_tag_id" label="分类名称">
        <a-space>
          <a-select
            style="width: 400px"
            v-model:value="scriptData.script_line_tag_id"
            placeholder="请选择分类名称"
          >
            <a-select-option
              :key="item.id"
              :value="item.id"
              v-for="item in typeList"
              >{{ item.name }}</a-select-option
            >
          </a-select>
        </a-space>
      </a-form-item> -->
      <a-form-item label="音频配置">
        <a-space :size="24">
          <span
            >{{ scriptData?.audio_config?.name }}
            {{ scriptData?.audio_config?.human_style ? "-" : "" }}
            {{ scriptData?.audio_config?.human_style }}</span
          >
          <a-button type="link" @click="handleOpenDubbing">编辑</a-button>
        </a-space>
      </a-form-item>
      <a-form-item label="场景音频字幕">
        <a-space :size="24">
          <a-radio-group v-model:value="scriptData.subtitle_status">
            <a-radio value="on">开启</a-radio>
            <a-radio value="off">关闭</a-radio>
          </a-radio-group>
          <a-button
            v-if="scriptData.subtitle_status === 'on'"
            @click="handleOpenSubtitle"
            type="link"
            >字体效果</a-button
          >
        </a-space>
      </a-form-item>

      <a-page-header
        title="脚本内容"
        sub-title="脚本一般由多个场景组成，场景内可添加台词（及生成的音频）和视频等内容"
      />
      <a-card
        style="margin-top: 10px"
        v-for="(item, index) in scriptData.script_scenes"
        :key="index"
        :headStyle="{ background: '#fafafc' }"
      >
        <template #title>
          <div class="card_title">
            <MenuOutlined style="cursor: move" />
            <span style="margin-left: 10px; font-size: 14px">场景名称：</span>
            <a-input
              style="width: 200px; margin-left: 5px"
              placeholder="如: 项目门头"
              v-model:value="item.name"
            />
          </div>
        </template>
        <template #extra>
          <div class="scene_time">
            <a-space>
              <span>场景时长：</span>
              <a-radio-group
                @change="
                  (e) => {
                    if (e.target.value == '0') {
                      item.seconds = 5;
                    }
                  }
                "
                style="margin-left: 10px"
                v-model:value.trim="item.seconds_type"
              >
                <a-radio :value="0">自动</a-radio>
                <a-radio :value="1">固定</a-radio>
              </a-radio-group>
              <a-space>
                <a-input-number
                  v-if="item.seconds_type == 1"
                  style="width: 90px"
                  placeholder="请输入"
                  addon-after="秒"
                  :max="30"
                  :min="1"
                  v-model:value="item.seconds"
                />
                <a-button
                  style="color: red"
                  type="link"
                  @click="deleteCard(index)"
                  >删除</a-button
                >
              </a-space>
            </a-space>
          </div>
        </template>

        <div class="card_content">
          <div class="content_name">场景描述（选填）</div>
          <div class="content_con">
            <a-textarea
              style="margin-top: 5px"
              v-model:value="item.remark"
              placeholder="如 这个场景体现了项目的门头"
              :maxLength="50"
              :auto-size="{ minRows: 3, maxRows: 3 }"
            />
          </div>

          <div
            style="
              border-top: 1px solid #eee;
              padding: 20px 0;
              margin-top: 20px;
            "
          >
            <div v-if="item.line_audio?.length > 0" class="line-list">
              <div class="title">
                <div>台词</div>
                <div>场景音频</div>
              </div>
              <div
                v-for="(it, idx) in item.line_audio"
                :key="idx"
                class="line-item"
              >
                <div>
                  <div class="text-ellipsis">{{ it?.content }}</div>
                  <div><api-outlined /></div>
                </div>
                <div>
                  <!-- <div v-if="it?.audio_url"> -->
                  <div v-if="it?.conver_to_audio === 'on'">
                    <a-space>
                      <play-circle-outlined @click="handlePlayAudio(it)" />
                      <span>{{ it?.duration_text }}</span>
                    </a-space>
                  </div>
                  <div v-if="it?.conver_to_audio === 'off'">
                    未生成，点击<span
                      @click="handleGenerate(it)"
                      style="color: #2878FF; cursor: pointer"
                      >生成</span
                    >
                  </div>

                  <a-popover>
                    <template #content>
                      <div>
                        <a-button
                          @click="handleEditLine(it, idx, index)"
                          type="link"
                          >编辑</a-button
                        >
                      </div>
                      <div>
                        <a-button
                          @click="handleDeleteLine(idx, index)"
                          type="link"
                          >删除</a-button
                        >
                      </div>
                    </template>
                    <setting-outlined />
                  </a-popover>
                </div>
              </div>
            </div>
            <a-button @click="handleAddActorsLine(index)">
              <template #icon>
                <PlusOutlined />
              </template>
              添加台词
            </a-button>
          </div>
        </div>
      </a-card>

      <div class="form_con" style="margin-top: 20px" @click="handleAddScene">
        <a-button type="primary">
          <template #icon>
            <PlusOutlined />
          </template>
          添加场景
        </a-button>
      </div>
    </a-form>

    <a-drawer
      v-model:visible="classifyVisible"
      title="创建分类"
      :width="600"
      :closable="false"
    >
      <a-form :model="formRef" layout="vertical">
        <a-form-item label="分类名称" v-bind="validateInfosType.name">
          <a-input
            :maxlength="10"
            v-model:value="formRef.name"
            style="width: 100%"
            placeholder="请输入分类名称"
          />
        </a-form-item>
        <a-form-item label="排序" v-bind="validateInfosType.sort">
          <a-input-number
            v-model:value="formRef.sort"
            :min="0"
            style="width: 100%"
            placeholder="数值越小越靠前"
          />
        </a-form-item>
      </a-form>

      <div class="drawer-footer">
        <a-button @click="classifyVisible = false">取消</a-button>
        <a-button
          type="primary"
          @click="handleTypeSubmit"
          style="margin-left: 10px"
          >保存</a-button
        >
      </div>
    </a-drawer>

    <template #footer>
      <div style="text-align: right">
        <a-space>
          <a-button type="default" @click="handleCancel">取消</a-button>
          <a-button type="primary" @click="handleScriptSubmit">确认</a-button>
        </a-space>
      </div>
    </template>

    <a-modal
      :width="650"
      title="添加台词"
      :visible="actorsLineVisible"
      @cancel="actorsLineVisible = false"
      :confirm-loading="generateLoading"
      @ok="handleLineSubmit"
    >
      <a-form :model="actorsLineData">
        <a-form-item label="" v-bind="validateInfosLine.content">
          <a-input
            :maxlength="64"
            placeholder="如 门店终于上团购了 现在下单只要99元..."
            v-model:value="actorsLineData.content"
            show-count
          />
        </a-form-item>
        <a-form-item label="" v-bind="validateInfosLine.conver_to_audio">
          <a-space>
            <a-switch
              unCheckedValue="off"
              checkedValue="on"
              v-model:checked="actorsLineData.conver_to_audio"
            />
            <span style="margin-left: 10px">同时生成音频素材</span>
          </a-space>
        </a-form-item>
      </a-form>
    </a-modal>

    <DubbingSetting
      :data="scriptData?.audio_config"
      :visible="dubbingVisible"
      @close="dubbingVisible = false"
      @change="changeDubbingSetting"
    />
    <SubtitleSettings
      :data="scriptData.subtitle_config"
      :scriptId="data?.id"
      :visible="subtitleVisible"
      @close="subtitleVisible = false"
      @change="changeSubtitleSetting"
    />

    <PreviewModal
      :visible="visiblePreview"
      :title="previewData?.content"
      :url="previewData?.audio_url"
      type="audio"
      @onCancel="visiblePreview = false"
    />
  </a-drawer>
</template>

<script>
import {
  defineComponent,
  reactive,
  toRefs,
  computed,
  watch,
  toRaw,
  h,
  onBeforeUnmount,
  createVNode,
} from "vue";
import request from "@/common/utils/request";
import { useRouter } from "vue-router";
import { Modal, notification, message, Form } from "ant-design-vue";
import {
  MenuOutlined,
  PlusOutlined,
  ApiOutlined,
  PlayCircleOutlined,
  SettingOutlined,
} from "@ant-design/icons-vue";
import DubbingSetting from "./DubbingSetting.vue";
import SubtitleSettings from "./SubtitleSettings.vue";
import PreviewModal from "@/components/PreviewModal/index.vue";


const useForm = Form.useForm;

function updateScript(params) {
  return request.put("/work_ai", "/user/shotstack/script-line/update", params);
}

function addScript(params) {
  return request.post("/work_ai", "/user/shotstack/script-line/add", params);
}

function editScript(params) {
  if (params?.id) {
    return updateScript(params);
  } else {
    return addScript(params);
  }
}

// 新增分类
function addType(params) {
  return request.post(
    "/work_ai",
    "/user/shotstack/script-line/tag/add",
    params
  );
}

// 编辑分类
function updateType(params) {
  return request.put(
    "/work_ai",
    "/user/shotstack/script-line/tag/update",
    params
  );
}

function editType(params) {
  if (params?.id) {
    return updateType(params);
  } else {
    return addType(params);
  }
}

// 如果更换了“脚本配置”，取用接口/work_ai/user/shotstack/script-line/detail，返回的参数data.detail.audio_config.voice_type
function getScriptDetail(scriptLineId) {
  // scriptLineId
  return request.get("/work_ai", "/user/shotstack/script-line/detail", {
    scriptLineId,
  });
}

function getTextToAudio(params) {
  return request.post("/work_ai", "/user/shotstack/text-to-audio", params);
}

function getTypeList(params) {
  return request.get(
    "/work_ai",
    "/user/shotstack/script-line/tag/list",
    params
  );
}

const INITIAL_SCENE = {
  // 脚本名称
  title: "",
  // 分类名称
  script_type: "user",
  // 场景音频字幕
  subtitle_status: "on",
  script_line_tag_id: 0,
  // 音频配置
  audio_config: {
    name: "智瑞",
    human_style: "新闻播音员",
    gender_type: "male",
    gender: "male",
    voice_id: 5,
    voice_type: 101021,
    emotion_style_key: "neutral",
    volume: 0,
    speed: 1,
    emotion_category: "news",
    emotion_intensity: 100,
  },
  // 字体效果
  subtitle_config: {
    font_family: "HappyZcool-2016",
    font_size: 32,
    material_url:
      "https://bailing-1305744786.cos.ap-nanjing.myqcloud.com/upload/material/20231225/fonts/zhan_ku_kuai_le_ti_ttf.ttf",
    css: "b {font-family: 'HappyZcool-2016','HappyZcool-2016';font-size:32;color: #FFF000;background: ;opacity: 1;text-align: center;}",
    html: "<p></p>",
    color: "#FFF000",
    backgroundColor: "",
    opacity: 1,
    align_type: "center",
    verticle_position: "center",
    config: {
      start: 0,
      length: 5,
      x: 0,
      y: 0,
      transition_in: "",
      transition_out: "",
      effect: "",
      position: "center",
    },
  },
  // 脚本内容
  script_scenes: [
    {
      name: "",
      seconds_type: 0,
      seconds: 5,
      remark: "",
      line_audio: [
        // {
        //   id: 78126,
        //   script_id: 3147,
        //   scene_id: 15863,
        //   content: "121231",
        //   job_id: "65ae37d0558f41705916368",
        //   size: 132644,
        //   duration: 2762,
        //   audio: {
        //     job_id: "65ae37d0558f41705916368",
        //     content: "121231",
        //     media_url:
        //       "/s/20240122/text_to_audio/mpmsjJ/WAV/65ae37d14e95a.WAV",
        //     status: "succeeded",
        //   },
        // },
        // {
        //   id: 7826,
        //   script_id: 3147,
        //   scene_id: 15863,
        //   content: "sssss",
        //   job_id: "65ae37d0558f41705916368",
        //   size: 132644,
        //   duration: 2762,
        //   audio: {
        //     job_id: "65ae37d0558f41705916368",
        //     content: "121231",
        //     media_url:
        //       "/s/20240122/text_to_audio/mpmsjJ/WAV/65ae37d14e95a.WAV",
        //     status: "succeeded",
        //   },
        // },
      ],
    },
  ],
};

export default defineComponent({
  name: "ScriptSetting",
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    data: {
      type: Object,
      default: () => {},
    },
  },
  components: {
    MenuOutlined,
    PlusOutlined,
    ApiOutlined,
    PlayCircleOutlined,
    SettingOutlined,
    DubbingSetting,
    SubtitleSettings,
    PreviewModal,
  },

  setup(props, context) {
    const router = useRouter();
    const state = reactive({
      record: {},
      dubbingVisible: false,
      subtitleVisible: false,
      actorsLineVisible: false,
      visiblePreview: false,
      classifyVisible: false,
      previewData: {},
      typeList: [],
      generateLoading: false,
      // scriptData: {},
    });

    const scriptData = reactive({
      // 脚本名称
      title: "",
      // 分类名称
      script_type: "user",
      // 场景音频字幕
      subtitle_status: "on",
      // 分类id
      script_line_tag_id: 0,
      // 音频配置
      audio_config: {
        // lang: "zh-CN",
        // mood: "general",
        // role: "zh-CN-XiaochenNeural",
        // volume: 100,
        // speech_rate: 1,
        name: "智瑞",
        human_style: "新闻播音员",
        gender_type: "male",
        gender: "male",
        voice_id: 5,
        voice_type: 101021,
        emotion_style_key: "neutral",
        volume: 0,
        speed: 1,
        emotion_category: "news",
        emotion_intensity: 100,
      },
      // 字体效果
      subtitle_config: {
        font_family: "HappyZcool-2016",
        font_size: 32,
        material_url:
          "https://bailing-1305744786.cos.ap-nanjing.myqcloud.com/upload/material/20231225/fonts/zhan_ku_kuai_le_ti_ttf.ttf",
        css: "b {font-family: 'HappyZcool-2016','HappyZcool-2016';font-size:32;color: #FFF000;background-color: transparent;opacity: 1;text-align: center;}",
        html: "<p></p>",
        color: "#FFF000",
        backgroundColor: "",
        opacity: 1,
        align_type: "center",
        verticle_position: "center",
        config: {
          start: 0,
          length: 5,
          x: 0,
          y: 0,
          transition_in: "",
          transition_out: "",
          effect: "",
          position: "center",
        },
      },
      // 脚本内容
      script_scenes: [
        {
          name: "",
          seconds_type: 0,
          seconds: 5,
          remark: "",
          line_audio: [
            // {
            //   id: 78126,
            //   script_id: 3147,
            //   scene_id: 15863,
            //   content: "121231",
            //   job_id: "65ae37d0558f41705916368",
            //   size: 132644,
            //   duration: 2762,
            //   audio: {
            //     job_id: "65ae37d0558f41705916368",
            //     content: "121231",
            //     media_url:
            //       "/s/20240122/text_to_audio/mpmsjJ/WAV/65ae37d14e95a.WAV",
            //     status: "succeeded",
            //   },
            // },
            // {
            //   id: 7826,
            //   script_id: 3147,
            //   scene_id: 15863,
            //   content: "sssss",
            //   job_id: "65ae37d0558f41705916368",
            //   size: 132644,
            //   duration: 2762,
            //   audio: {
            //     job_id: "65ae37d0558f41705916368",
            //     content: "121231",
            //     media_url:
            //       "/s/20240122/text_to_audio/mpmsjJ/WAV/65ae37d14e95a.WAV",
            //     status: "succeeded",
            //   },
            // },
          ],
        },
      ],
    });

    const actorsLineData = reactive({
      content: "",
      conver_to_audio: "on",
    });
    const rulesRef = computed(() => {
      return {
        title: [{ required: true, message: "脚本名称不能为空" }],
        // script_line_tag_id: [{ required: true, message: "脚本分类不能为空" }],
        audio_config: [{ required: true, message: "音频配置不能为空" }],
        subtitle_status: [{ required: true, message: "场景音频字幕不能为空" }],
      };
    });
    const rulesLineRef = computed(() => {
      return {
        content: [{ required: true, message: "请输入台词" }],
      };
    });

    const formRef = reactive({
      name: null,
      sort: 0,
    });
    const rulesTypeRef = computed(() => {
      return {
        name: [{ required: true, message: "分类名称不能为空" }],
      };
    });

    const { validate, validateInfos, resetFields } = useForm(
      scriptData,
      rulesRef
    );
    const { validate: validateType, validateInfos: validateInfosType } =
      useForm(formRef, rulesTypeRef);
    const { validate: validateLine, validateInfos: validateInfosLine } =
      useForm(actorsLineData, rulesLineRef);

    const getTypeDataSource = () => {
      let params = {
        page: 1,
        pageSize: 10000,
      };

      getTypeList(params).then((res) => {
        if (res.list) {
          state.typeList = res.list;
        }
      });
    };

    // 音频配置
    const changeDubbingSetting = (data) => {
      console.log(data,'音频data');
      scriptData.audio_config = data;
      state.dubbingVisible = false;
    };

    // 字幕配置
    const changeSubtitleSetting = (data) => {
      console.log(data);
      scriptData.subtitle_config = data;
      state.subtitleVisible = false;
    };

    const deleteCard = (index) => {
      if (scriptData.script_scenes?.length == 1) {
        message.warn("至少有一个场景");
        return;
      }
      scriptData.script_scenes.splice(index, 1);
    };

    const handleAddActorsLine = (parentIndex) => {
      actorsLineData.parentIndex = parentIndex;
      actorsLineData.index =
        scriptData.script_scenes[parentIndex]?.line_audio?.length;
      actorsLineData.content = "";
      actorsLineData.conver_to_audio = "on";
      state.actorsLineVisible = true;
    };

    const handleGenerate = (item) => {
      const params = {
        content: item.content,
        volume: scriptData.audio_config.volume,
        speed: scriptData.audio_config.speed,
        // 传值修改
        voice_type: scriptData.audio_config.voice_type,
        emotion_category: scriptData.audio_config.emotion_category,
        emotion_intensity: scriptData.audio_config.emotion_intensity,
      };

      if (state.generateLoading) {
        return;
      }

      state.generateLoading = true;

      getTextToAudio(params)
        .then((res) => {
          state.generateLoading = false;
          if (res?.result?.url) {
            item.duration_text = res.result?.duration_text;
            item.conver_to_audio = "on";
            item.duration = res.result?.duration_ts;
            item.audio_url = res.result?.url;
          }
        })
        .catch(() => {
          state.generateLoading = false;
        });
    };

    const handleEditLine = (item, idx, parentIndex) => {
      actorsLineData.parentIndex = parentIndex;
      actorsLineData.index = idx;
      actorsLineData.content = item.content;
      actorsLineData.conver_to_audio = item?.conver_to_audio;
      state.actorsLineVisible = true;
    };

    const handleDeleteLine = (index, parentIndex) => {
      scriptData.script_scenes[parentIndex]?.line_audio?.splice(index, 1);
    };

    const handlePlayAudio = (item) => {
      state.previewData = item;
      state.visiblePreview = true;
    };

    // 添加场景
    const handleAddScene = () => {
      scriptData.script_scenes.push({
        name: "",
        seconds_type: 0,
        seconds: 5,
        remark: "",
        line_audio: [],
      });
    };

    const handleLineSubmit = () => {
      // 添加台词
      validateLine().then(() => {
        if (actorsLineData.conver_to_audio === "on") {
          const params = {
            content: actorsLineData.content,
            volume: scriptData.audio_config.volume,
            speed: scriptData.audio_config.speed,
            voice_type: scriptData.audio_config.voice_type,
            emotion_category: scriptData.audio_config.emotion_category,
            emotion_intensity: scriptData.audio_config.emotion_intensity,
          };

          state.generateLoading = true;

          getTextToAudio(params)
            .then((res) => {
              state.generateLoading = false;
              if (res?.result?.url) {
                console.log(res);
                scriptData.script_scenes[actorsLineData.parentIndex].line_audio[
                  actorsLineData.index
                ] = {
                  content: actorsLineData.content,
                  conver_to_audio: actorsLineData?.conver_to_audio,
                  duration_text: res?.result?.duration_text,
                  duration: res?.result?.duration_ts,
                  audio_url: res?.result?.url,
                };
                state.actorsLineVisible = false;
              }
            })
            .catch(() => {
              state.generateLoading = false;
            });
        } else {
          scriptData.script_scenes[actorsLineData.parentIndex].line_audio[
            actorsLineData.index
          ] = {
            content: actorsLineData.content,
            conver_to_audio: actorsLineData.conver_to_audio,
          };
          state.actorsLineVisible = false;
        }
      });
    };

    const handleTypeSubmit = () => {
      validateType().then(() => {
        const params = {
          ...formRef,
        };
        editType(params).then(() => {
          getTypeDataSource();
          state.classifyVisible = false;
        });
      });
    };

    const handleOpenType = () => {
      state.classifyVisible = true;
    };

    const handleOpenDubbing = () => {
      state.dubbingVisible = true;
    };

    const handleOpenSubtitle = () => {
      state.subtitleVisible = true;
    };

    const handleCancel = () => {
      context.emit("close");
    };

    const handleScriptSubmit = () => {
      validate().then(() => {
        // id存在 编辑
        const params = {
          ...scriptData,
        };
        if (scriptData?.script_scenes?.find((i) => !i.name)) {
          message.warning("场景名称不能为空");
          return;
        }
        delete params.id;
        if (props.data?.id) {
          params.id = props.data.id;
        }

        editScript(params).then((res) => {
          message.success("保存成功");
          context.emit("success");
        });
      });
    };

    // getTypeDataSource();

    watch(
      () => props.visible,
      (val) => {
        if (val && !props.data?.id) {
          Object.assign(scriptData, {
            ...JSON.parse(JSON.stringify(INITIAL_SCENE)),
          });
          delete scriptData?.id;
          scriptData.script_line_tag_id = 0;
          resetFields();
          return;
        }
        if (val && props.data.id) {
          getScriptDetail(props.data?.id).then((res) => {
            Object.assign(scriptData, res?.detail);
          });
        }
      }
    );

    return {
      actorsLineData,
      scriptData,
      formRef,
      ...toRefs(state),
      validateInfosType,
      validateInfos,
      validateInfosLine,
      handleCancel,
      handleScriptSubmit,
      handleOpenDubbing,
      handleOpenSubtitle,
      handleAddActorsLine,
      handleLineSubmit,
      deleteCard,
      handleEditLine,
      handleDeleteLine,
      changeDubbingSetting,
      changeSubtitleSetting,
      handleAddScene,
      handleGenerate,
      handlePlayAudio,
      handleOpenType,
      handleTypeSubmit,
    };
  },
});
</script>

<style lang="less" scoped>
.line-list {
  margin-bottom: 20px;
  .title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    > div {
      height: 20px;
      line-height: 20px;
    }
    > div:nth-child(1) {
      width: 60%;
    }
    > div:nth-child(2) {
      width: 40%;
    }
  }
  .line-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 7px;
    > div:nth-child(1) {
      width: 60%;
      display: flex;
      align-items: center;
      justify-content: space-between;
      > div:nth-child(1) {
        padding: 7px 10px;
        width: calc(100% - 30px);
        background: #fafafc;
      }
      > div:nth-child(2) {
        width: 30px;
        display: flex;
        align-items: center;
        justify-content: center;
      }
    }
    > div:nth-child(2) {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 7px 10px;
      width: 40%;
      background: #fafafc;
    }
  }
}
</style>
